﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Week1.world
{
    public class DrawPrimitive : Microsoft.Xna.Framework.DrawableGameComponent
    {

        player.Camera oCamera;
        protected VertexPositionColor[] oVertexClr;
        int iVerticesIdx = 0;
        int iPrimitiveCount = 0;
        BasicEffect oEffect;
        PrimitiveType oPrimitiveType;

        public DrawPrimitive(Game game, player.Camera camera, int verticesCount, PrimitiveType primitiveType)
            : base(game)
        {
            oCamera = camera;
            oPrimitiveType = primitiveType;

            oVertexClr = new VertexPositionColor[verticesCount];

            for (int iDx = 0; iDx < verticesCount; iDx++)
            {
                oVertexClr[iDx] = new VertexPositionColor();
            }
        }

        public void addPoint(Vector3 position, Color color)
        {
            oVertexClr[iVerticesIdx].Color = color;
            oVertexClr[iVerticesIdx++].Position = position;
        }

        public void setPointAt(int index, Vector3 position, Color color)
        {
            oVertexClr[index].Color = color;
            oVertexClr[index].Position = position;
        }
        

        public Vector3 getPointAt(int index)
        {
            return oVertexClr[index].Position;
        }


        public override void Initialize()
        {
            setPrimitiveCount();

            base.Initialize();
        }

        /// <summary>
        /// call this method to reset the primitive count at the end of addPoint or setPoint methods.
        /// </summary>
        public void setPrimitiveCount()
        {
            if (oPrimitiveType == PrimitiveType.LineList)
                iPrimitiveCount = iVerticesIdx / 2;
            else if (oPrimitiveType == PrimitiveType.LineStrip)
                iPrimitiveCount = iVerticesIdx - 1;
            else if (oPrimitiveType == PrimitiveType.TriangleList)
                iPrimitiveCount = iVerticesIdx / 3;
            else if (oPrimitiveType == PrimitiveType.TriangleStrip)
                iPrimitiveCount = iVerticesIdx - 2;
        }

        public void forceLoadContent()
        {
            LoadContent();
        }

        protected override void LoadContent()
        {
            if (oEffect == null)
                oEffect = new BasicEffect(this.Game.GraphicsDevice);
            
            base.LoadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            this.GraphicsDevice.BlendState = BlendState.Opaque;
            oEffect.LightingEnabled = false;
            oEffect.VertexColorEnabled = true;
            oEffect.World = Matrix.Identity;
            oEffect.View = oCamera.View;
            oEffect.Projection = oCamera.Projection;

            EffectPass oPass = oEffect.CurrentTechnique.Passes[0];
            
            oPass.Apply();
            GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(oPrimitiveType, oVertexClr, 0, iPrimitiveCount);

            base.Draw(gameTime);
        }
    }
}
